package com.heu.blood.analysis.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.heu.blood.analysis.exception.AnalysisExceptionEnum;
import com.heu.blood.analysis.vo.BloodSampleTransfusionDeliveryVo;
import com.heu.blood.analysis.vo.BloodSampleTransfusionReportVo;
import com.heu.blood.application.dao.BloodApplicationDao;
import com.heu.blood.application.dictenum.ApplicationStateEnum;
import com.heu.blood.application.entity.BloodApplicationEntity;
import com.heu.blood.application.service.BloodApplicationService;
import com.heu.blood.autologous.vo.BloodApplicationAutologousVo;
import com.heu.blood.common.Constant.ConstantData;
import com.heu.blood.common.enums.BloodSampleEnum;
import com.heu.blood.common.utils.GenerateNumberBySnowFlake;
import com.heu.blood.globalExceptionHandler.MyException;
import com.heu.blood.match.exception.TimeException;
import com.heu.blood.security.dao.UserDao;
import com.heu.blood.security.entity.UserEntity;
import com.heu.blood.security.exception.UserLoginException;
import com.heu.blood.transfusion.entity.TransfusionApplicationEntity;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heu.blood.common.utils.PageUtils;
import com.heu.blood.common.utils.Query;

import com.heu.blood.analysis.dao.BloodSampleInfoTransfusionDao;
import com.heu.blood.analysis.entity.BloodSampleInfoTransfusionEntity;
import com.heu.blood.analysis.service.BloodSampleInfoTransfusionService;
import org.springframework.transaction.annotation.Transactional;

import static com.heu.blood.common.enums.CommonEnum.IF_SHOW;


@Service("bloodSampleInfoTransfusionService")
public class BloodSampleInfoTransfusionServiceImpl extends ServiceImpl<BloodSampleInfoTransfusionDao, BloodSampleInfoTransfusionEntity> implements BloodSampleInfoTransfusionService {
    @Autowired
    BloodSampleInfoTransfusionDao bloodSampleInfoTransfusionDao;

    @Autowired
    BloodApplicationDao bloodApplicationDao;

    @Autowired
    BloodApplicationService bloodApplicationService;

    @Autowired
    private UserDao userDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        BloodSampleInfoTransfusionEntity bloodSampleInfoTransfusionEntity = new BloodSampleInfoTransfusionEntity();
        if (Strings.isNotBlank((String) params.get("transfusionId"))){
            bloodSampleInfoTransfusionEntity.setApplicationId((String) params.get("transfusionId")); // 添加transfusionId
        }
        if (Strings.isNotBlank((String) params.get("patientId"))){
            bloodSampleInfoTransfusionEntity.setPatientId((String) params.get("patientId")); // 添加patientId
        }
        if (Strings.isNotBlank((String) params.get("aboBloodType"))){
            bloodSampleInfoTransfusionEntity.setAboBloodType((String) params.get("aboBloodType")); // 添加aboBloodType
        }
        if (Strings.isNotBlank((String) params.get("rhBloodType"))){
            bloodSampleInfoTransfusionEntity.setRhBloodType((String) params.get("rhBloodType")); // 添加rhBloodType
        }
        if(Strings.isNotBlank((String) params.get("patientName")))
            bloodSampleInfoTransfusionEntity.setPatientName((String)params.get("patientName"));
        if(Strings.isNotBlank((String) params.get("collector")))
            bloodSampleInfoTransfusionEntity.setCollector((String)params.get("collector"));
        if(Strings.isNotBlank((String) params.get("recipient")))
            bloodSampleInfoTransfusionEntity.setRecipient((String)params.get("recipient"));
        if(Strings.isNotBlank((String) params.get("bloodSampleInfoTransfusionId")))
            bloodSampleInfoTransfusionEntity.setBloodSampleInfoTransfusionId((String)params.get("bloodSampleInfoTransfusionId"));

        String collectStartTime = null;
        String collectEndTime = null;
        if(Strings.isNotBlank((String)params.get("collectStartTime")))
            collectStartTime = (String)params.get("collectStartTime");
        if(Strings.isNotBlank((String)params.get("collectEndTime")))
            collectEndTime = (String)params.get("collectEndTime");
        String receivedStartTime = null;
        String receivedEndTime = null;
        if(Strings.isNotBlank((String)params.get("receivedStartTime")))
            receivedStartTime = (String)params.get("receivedStartTime");
        if(Strings.isNotBlank((String)params.get("receivedEndTime")))
            receivedEndTime = (String)params.get("receivedEndTime");


        LambdaQueryWrapper<BloodSampleInfoTransfusionEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(bloodSampleInfoTransfusionEntity.getApplicationId()),
                BloodSampleInfoTransfusionEntity::getApplicationId, bloodSampleInfoTransfusionEntity.getApplicationId())
                .eq(Strings.isNotBlank(bloodSampleInfoTransfusionEntity.getPatientId()),
                        BloodSampleInfoTransfusionEntity::getPatientId, bloodSampleInfoTransfusionEntity.getPatientId())
                .eq(Strings.isNotBlank(bloodSampleInfoTransfusionEntity.getAboBloodType()),
                        BloodSampleInfoTransfusionEntity::getAboBloodType, bloodSampleInfoTransfusionEntity.getAboBloodType())
                .eq(Strings.isNotBlank(bloodSampleInfoTransfusionEntity.getRhBloodType()),
                        BloodSampleInfoTransfusionEntity::getRhBloodType, bloodSampleInfoTransfusionEntity.getRhBloodType())
                .eq(Strings.isNotBlank(bloodSampleInfoTransfusionEntity.getPatientName()),
                        BloodSampleInfoTransfusionEntity::getPatientName, bloodSampleInfoTransfusionEntity.getPatientName())
                .eq(Strings.isNotBlank(bloodSampleInfoTransfusionEntity.getCollector()),
                        BloodSampleInfoTransfusionEntity::getCollector, bloodSampleInfoTransfusionEntity.getCollector())
                .eq(Strings.isNotBlank(bloodSampleInfoTransfusionEntity.getRecipient()),
                        BloodSampleInfoTransfusionEntity::getRecipient, bloodSampleInfoTransfusionEntity.getRecipient())
                .eq(Strings.isNotBlank(bloodSampleInfoTransfusionEntity.getBloodSampleInfoTransfusionId()),
                        BloodSampleInfoTransfusionEntity::getBloodSampleInfoTransfusionId, bloodSampleInfoTransfusionEntity.getBloodSampleInfoTransfusionId())
                .ge(Strings.isNotBlank(collectStartTime),BloodSampleInfoTransfusionEntity::getCollectTime,collectStartTime)
                .le(Strings.isNotBlank(collectEndTime),BloodSampleInfoTransfusionEntity::getCollectTime,collectEndTime)
                .ge(Strings.isNotBlank(receivedStartTime), BloodSampleInfoTransfusionEntity::getReceivedTime,receivedStartTime)
                .le(Strings.isNotBlank(receivedEndTime), BloodSampleInfoTransfusionEntity::getReceivedTime,receivedEndTime)
                .eq(BloodSampleInfoTransfusionEntity::getIfShow, IF_SHOW.code());
        queryWrapper.orderByDesc(BloodSampleInfoTransfusionEntity::getGmtModified);
        IPage<BloodSampleInfoTransfusionEntity> page = this.page(
                new Query<BloodSampleInfoTransfusionEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    public BloodSampleTransfusionReportVo selectSamplePatientReport(String bloodSampleId) {
        return bloodSampleInfoTransfusionDao.selectSamplePatientReport(bloodSampleId);
    }


    @Override
    public PageUtils selectSamplePatientReportQuery(BloodSampleTransfusionReportVo bloodSampleTransfusionReportVo) {

        // 时间格式化，解决Date->String 报错
        String startTime = bloodSampleTransfusionReportVo.getStartTime();
        String endTime = bloodSampleTransfusionReportVo.getEndTime();


        if (Strings.isNotBlank(startTime) && Strings.isNotBlank(endTime)) {
            if (startTime.compareTo(endTime) > 0) {
                throw new MyException(TimeException.TIME_OUTLINE);
            }
        }

        QueryWrapper<BloodSampleTransfusionReportVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(bloodSampleTransfusionReportVo.getPatientId()), "pi.patient_id",
                bloodSampleTransfusionReportVo.getPatientId())
                .eq(Strings.isNotBlank(bloodSampleTransfusionReportVo.getPatientName()), "pi.patient_name",
                        bloodSampleTransfusionReportVo.getPatientName())
                .eq(Strings.isNotBlank(bloodSampleTransfusionReportVo.getBloodSampleInfoTransfusionId()), "bsp.blood_sample_info_transfusion_id",
                        bloodSampleTransfusionReportVo.getBloodSampleInfoTransfusionId())
                .eq(Strings.isNotBlank(bloodSampleTransfusionReportVo.getApplicationId()), "bsp.application_id",
                        bloodSampleTransfusionReportVo.getApplicationId())
                .ge(Strings.isNotBlank(bloodSampleTransfusionReportVo.getStartTime()), "bsp.review_time",
                        bloodSampleTransfusionReportVo.getStartTime())
                .le(Strings.isNotBlank(bloodSampleTransfusionReportVo.getEndTime()), "bsp.review_time",
                        bloodSampleTransfusionReportVo.getEndTime());

        Map<String, Object> params = new HashMap<>();

        if (Strings.isNotBlank(bloodSampleTransfusionReportVo.getLimit())){
            params.put("limit", bloodSampleTransfusionReportVo.getLimit());
        }
        if (Strings.isNotBlank(bloodSampleTransfusionReportVo.getPage())){
            params.put("page", bloodSampleTransfusionReportVo.getPage());
        }

        IPage<BloodSampleTransfusionReportVo> page = bloodSampleInfoTransfusionDao.selectSamplePatientReportQuery(
                new Query<BloodSampleTransfusionReportVo>().getPage(params),
                queryWrapper
        );


        return new PageUtils(page);
    }

    @Override
    public List<BloodSampleInfoTransfusionEntity> selectSampleByBloodId(String bloodId) {
        LambdaQueryWrapper<BloodSampleInfoTransfusionEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(bloodId), BloodSampleInfoTransfusionEntity::getBloodId, bloodId);
        List<BloodSampleInfoTransfusionEntity> entities = bloodSampleInfoTransfusionDao.selectList(queryWrapper);

        return entities;
    }

    @Override
    public List<BloodSampleInfoTransfusionEntity> selectSampleByBloodSampleId(String bloodSampleId) {
        LambdaQueryWrapper<BloodSampleInfoTransfusionEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(bloodSampleId), BloodSampleInfoTransfusionEntity::getBloodSampleInfoTransfusionId, bloodSampleId)
                .eq(BloodSampleInfoTransfusionEntity::getIfShow, IF_SHOW.code());

        List<BloodSampleInfoTransfusionEntity> entities = bloodSampleInfoTransfusionDao.selectList(queryWrapper);
        return entities;
    }

    @Override
    @Transactional
    public BloodSampleInfoTransfusionEntity generateBloodSampleInfoTransfusionId(BloodSampleTransfusionDeliveryVo bloodSampleTransfusionDeliveryVo) {
//        根据申请单ID查找BloodSampleInfoTransfusionId,如果为null,按照雪花算法生成ID,并且把信息插入到application和自己的表中，最后更新状态
        String applicationId = bloodSampleTransfusionDeliveryVo.getApplicationId();
        String userName = bloodSampleTransfusionDeliveryVo.getUserName();
        BloodApplicationEntity bloodApplicationEntity = bloodApplicationService.selectBloodApplicationByApplicationId(applicationId);
        LambdaQueryWrapper<UserEntity> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(Strings.isNotBlank(userName),UserEntity::getUserName, userName);
        UserEntity userEntity = userDao.selectOne(userQuery);
        if (userEntity == null){
            throw new MyException(UserLoginException.NO_USER);
        }
        String userId = userEntity.getUserId();
        if (bloodApplicationEntity != null) {
//          TODO:打印接口 不应该放在这里
//            BloodApplicationEntity updatedPrintEntity = new BloodApplicationEntity();
//            updatedPrintEntity.setId(bloodApplicationEntity.getId());
////        修改打印状态
//            updatedPrintEntity.setIfPrint(Integer.parseInt(ApplicationStateEnum.PRINT.code()));
//            bloodApplicationService.updateById(updatedPrintEntity);
            String bloodSampleInfoTransfusionId = bloodApplicationEntity.getBloodSampleInfoTransfusionId();
            BloodSampleInfoTransfusionEntity bloodSampleInfoTransfusionEntity = new BloodSampleInfoTransfusionEntity();
//            缺少BloodSampleInfoTransfusionId
            if (bloodSampleInfoTransfusionId == null || "".equals(bloodSampleInfoTransfusionId)) {
                GenerateNumberBySnowFlake generateNumberBySnowFlake = new GenerateNumberBySnowFlake(ConstantData.SAMPLE_TRANSFUSION_NO_WORK_ID, ConstantData.SAMPLE_TRANSFUSION_NO_PREFIX);
                String sampleId = generateNumberBySnowFlake.genNumberByflag();
//                更新血液申请单表
//                bloodApplicationEntity.setBloodSampleInfoTransfusionId(sampleId);
                BloodApplicationEntity updatedEntity = new BloodApplicationEntity();
                updatedEntity.setId(bloodApplicationEntity.getId());
                updatedEntity.setBloodSampleInfoTransfusionId(sampleId);
                bloodApplicationService.updateById(updatedEntity);
//                信息插入血液样本表
                bloodSampleInfoTransfusionEntity.setBloodSampleInfoTransfusionId(sampleId);
                bloodSampleInfoTransfusionEntity.setPatientId(bloodApplicationEntity.getPatientId());
                bloodSampleInfoTransfusionEntity.setPatientName(bloodApplicationEntity.getPatientName());
                bloodSampleInfoTransfusionEntity.setApplicationId(applicationId);
                bloodSampleInfoTransfusionEntity.setSampleStatus(BloodSampleEnum.TO_BE_RECEIVED.code());
                bloodSampleInfoTransfusionEntity.setPatientType(bloodApplicationEntity.getPatientType());
                bloodSampleInfoTransfusionEntity.setAboBloodType(bloodApplicationEntity.getAboBloodType());
                bloodSampleInfoTransfusionEntity.setRhBloodType(bloodApplicationEntity.getRhBloodType());
                // 病人性别
                bloodSampleInfoTransfusionEntity.setGender(bloodApplicationEntity.getGender());
                // 病人年龄
                bloodSampleInfoTransfusionEntity.setAge(bloodApplicationEntity.getAge());
                // 病房
                bloodSampleInfoTransfusionEntity.setWard(bloodApplicationEntity.getWard());
                // 病床号
                bloodSampleInfoTransfusionEntity.setBedNumber(bloodApplicationEntity.getBedNumber());
                // 科室
                bloodSampleInfoTransfusionEntity.setDepartment(bloodApplicationEntity.getDepartment());
                //操作的护士id
                bloodSampleInfoTransfusionEntity.setOperatorId(userId);
                //操作的护士username
                bloodSampleInfoTransfusionEntity.setOperatorName(userName);

                bloodSampleInfoTransfusionDao.insert(bloodSampleInfoTransfusionEntity);
            } else { // 存在BloodSampleInfoTransfusionId
//                信息封装好直接返回
                bloodSampleInfoTransfusionEntity.setBloodSampleInfoTransfusionId(bloodSampleInfoTransfusionId);
                bloodSampleInfoTransfusionEntity.setPatientId(bloodApplicationEntity.getPatientId());
                bloodSampleInfoTransfusionEntity.setPatientName(bloodApplicationEntity.getPatientName());
                bloodSampleInfoTransfusionEntity.setApplicationId(applicationId);
                bloodSampleInfoTransfusionEntity.setPatientType(bloodApplicationEntity.getPatientType());
                bloodSampleInfoTransfusionEntity.setSampleStatus(BloodSampleEnum.TO_BE_RECEIVED.code());
                bloodSampleInfoTransfusionEntity.setPatientType(bloodApplicationEntity.getPatientType());
                // 病人性别
                bloodSampleInfoTransfusionEntity.setGender(bloodApplicationEntity.getGender());
                // 病人年龄
                bloodSampleInfoTransfusionEntity.setAge(bloodApplicationEntity.getAge());
                // 病房
                bloodSampleInfoTransfusionEntity.setWard(bloodApplicationEntity.getWard());
                // 病床号
                bloodSampleInfoTransfusionEntity.setBedNumber(bloodApplicationEntity.getBedNumber());
                // 科室
                bloodSampleInfoTransfusionEntity.setDepartment(bloodApplicationEntity.getDepartment());
                bloodSampleInfoTransfusionEntity.setAboBloodType(bloodApplicationEntity.getAboBloodType());
                bloodSampleInfoTransfusionEntity.setRhBloodType(bloodApplicationEntity.getRhBloodType());

                //操作的护士id
                bloodSampleInfoTransfusionEntity.setOperatorId(userId);
                //操作的护士username
                bloodSampleInfoTransfusionEntity.setOperatorName(userName);

                LambdaUpdateWrapper<BloodSampleInfoTransfusionEntity> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(BloodSampleInfoTransfusionEntity::getBloodSampleInfoTransfusionId, bloodSampleInfoTransfusionId)
                        .set(BloodSampleInfoTransfusionEntity::getOperatorId, userId)
                        .set(BloodSampleInfoTransfusionEntity::getOperatorName, userName);
                bloodSampleInfoTransfusionDao.update(null, updateWrapper);

            }

            return bloodSampleInfoTransfusionEntity;
        } else {
            throw new MyException(AnalysisExceptionEnum.ILLEGAL_PARAMS);
        }
    }

    @Override
    public int updateSampleStatusTORECEIVED(String bloodSampleId) {
//        0代表参数不合格 1代表bloodSampleInfoTransfusionEntity为null 2代表更新成功
        if (!Strings.isNotBlank(bloodSampleId)) {
            return 0;
        }
        LambdaQueryWrapper<BloodSampleInfoTransfusionEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Strings.isNotBlank(bloodSampleId), BloodSampleInfoTransfusionEntity::getBloodSampleInfoTransfusionId, bloodSampleId);
        BloodSampleInfoTransfusionEntity bloodSampleInfoTransfusionEntity = bloodSampleInfoTransfusionDao.selectOne(queryWrapper);

        LambdaQueryWrapper<BloodApplicationEntity> queryWrapper1=new LambdaQueryWrapper<>();
        queryWrapper1.eq(BloodApplicationEntity::getBloodSampleInfoTransfusionId,bloodSampleId)
                .orderByDesc(BloodApplicationEntity::getGmtModified);
        List<BloodApplicationEntity> bloodApplicationEntityList=bloodApplicationDao.selectList(queryWrapper1);

        BloodApplicationEntity latest=bloodApplicationEntityList.get(0);
        if (bloodSampleInfoTransfusionEntity != null) {
            BloodSampleInfoTransfusionEntity updateEntity = new BloodSampleInfoTransfusionEntity();
            BeanUtils.copyProperties(latest,updateEntity);
            updateEntity.setSampleStatus(BloodSampleEnum.RECEIVED.code());
            updateEntity.setId(bloodSampleInfoTransfusionEntity.getId());
            updateEntity.setGmtModified(new Date());
            this.updateById(updateEntity);
            return 2;
        }

        return 1;
    }


}